

#ifndef _SYMBOLTABLE_H
#define _SYMBOLTABLE_H
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <list>
#include "absyn.h"
#include "symboldefine.h"

using namespace std;

class SymbolTable {
private:
    const static int ERROR_RETURN = 0xffff; // 出错时返回
    const static int OFFSET_INC = 4;        // 偏移量每次增加值
    const static int MAXSIZE = 256;         // 层级的最大数量

    static int currentNestLevel;            // 当前所在的层级
    static int offset;                      // 当前偏移

    // 变量定义
    static unordered_map<string, list<VariableDefinition> > VariableDefinitionHashMap;

    // 类型定义
    static unordered_map<string, list<TypeDefinition> > TypeDefinitionHashMap;

    // 函数定义
    static unordered_map<string, list<FunctionDefinition> > FunctionDefinitionHashMap;

    // 过程定义
    static unordered_map<string, list<ProcedureDefinition> > ProcedureDefinitionHashMap;

    // 下标定义
	static vector<SubBoundDefinition> sdvector;

    // 数组定义
	static vector<ArrayDefinition> advector;

    // 结构体定义
	static vector<RecordDefinition> rdvector;

    // 每一层及的总偏移（占用空间的总大小）
    static int totalOffset[MAXSIZE];

public:
    // 增加过程或函数
    static int addProcOrFunc(TreeNode headNode);

    // 增加变量
    static void insertVariable(VariableDefinition VariableDefinition, int lineNumber);

    // 增加类型
    static void insertType(TypeDefinition TypeDefinition, int lineNumber);

    // 根据变量名查询变量
    static VariableDefinition lookupVar(string name, int cur_level);

    // 根据类型名查询自定义类型
    static TypeDefinition lookupType(string name, int cur_level);

    // 根据过程名查询过程
    static ProcedureDefinition lookupProc(string name, int cur_level);

    // 根据函数名查询函数
    static FunctionDefinition lookupFunc(string name, int cur_level);

    // 根据record名rec和其成员名a查询数据
    static LookupReturn lookupRecord(string rec, string a, int cur_level);

    // 初始化当前层级
    static void initScope();

    // 根据给定AST构建当前层级的符号表
    static int enterNewScope(TreeNode t);

    // 离开当前层级
    static int leaveScope();

    // 根据给定语法树更新符号表
    static int updateSymbolTable(TreeNode syntaxTree);

    // 给定一个树节点，将其表示的符号表插入到原本的当中
    static void insertNode(TreeNode t);
};

#endif
